//package com.xjh.config;
//
//import com.xjh.service.PasswordUserDetailsService;
//import com.xjh.utils.util.BCryptUtil;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.http.HttpMethod;
//import org.springframework.security.authentication.AuthenticationManager;
//import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
//import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
//import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
//import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
//import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
//import org.springframework.security.oauth2.provider.ClientDetailsService;
//import org.springframework.security.oauth2.provider.TokenGranter;
//import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
//import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
//import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
//import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
//import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
//import org.springframework.security.oauth2.provider.token.TokenStore;
//import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
//
//import javax.sql.DataSource;
//
///**
// * 授权服务配置:1.配置客户端、2.配置端点生成token 3.配置对token的相关操作
// *
// * @author XuJianHua
// * @version 1.0
// * @company 湖南安第斯信息科技有限公司, 版权所有
// * @date 2022/7/13 17:48
// */
//@Configuration
//@EnableAuthorizationServer// 这个注解必须加上,否则访问测试地址404
//public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
//    @Autowired
//    private AuthenticationManager authenticationManager;
//
//    @Qualifier("dataSource")
//    @Autowired
//    private DataSource dataSource;
//    //TokenGranter, 字面上的理解: 令牌授予者。
////    @Autowired
////    private TokenGranter tokenGranter;
//
//    @Autowired
//    private AuthorizationCodeServices authorizationCodeServices;
//
//    @Autowired
//    private PasswordUserDetailsService passwordUserDetailsService;
//
//    // 这两个在tokenConfig里，不知道为啥要弄到这里
//    @Bean
//    public TokenStore tokenStore() { //使用基于内存的普通令牌(直接往spring中注入一个基于内存的tokenStore)
//        return new InMemoryTokenStore();
//    }
//    @Autowired
//    private TokenStore tokenStore;
//    //会通过之前的ClientDetailsServiceConfigurer注入到Spring容器中
//    @Autowired
//    private ClientDetailsService clientDetailsService;
//
//
//    /**
//     * 1.配置客户端
//     */
//    /*AuthorizationServerEndpointsConfigurer 配置令牌服务。首选需要配置
//     token如何存取，以及客户端支持哪些类型的token。然后不同的令牌服务需要不同
//     的其他服务。authorization_code类型需要配置authorizationCodeServices来管
//     理授权码，password类型需要UserDetailsService来验证用户身份。*/
//
//    /*
//     * 设置认证信息的来源：此处使用数据库
//     * 可选方式
//     * 1.inMemory
//     * 2.JdbcClientDetailsService
//     */
//    /*1.1自定义的客户端管理服务*/
////    @Override
////    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
////        clients.withClientDetails(clientDetailsService());
////    }
//
////    @Bean
////    public ClientDetailsService clientDetailsService() {
////        return new JdbcClientDetailsService(dataSource);
////    }
//
//
//    /*1.基于内存的客户端管理服务*/
//    @Override
//    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//        clients.inMemory()
//                // clientId: 用来标识客户的ID。必须。
//                .withClient("client")
//                // secret: 客户端安全码，如果有的话。在微信登录中就是必须的。
//                .secret(BCryptUtil.encode("123456"))
//                // 客户端拥有的资源列表（如果设置了，客户端访问时则必须要有）
//                .resourceIds("test")
//                // 配置访问token的有效期
//                .accessTokenValiditySeconds(360000)
//                // 配置刷新token的有效期
//                .refreshTokenValiditySeconds(864000)
//                // 配置redirect_uri，用于授权成功后跳转
//                .redirectUris("http://www.baidu.com")
//                //authrizedGrantTypes：此客户端可以使用的授权类型，默认为空。在微信登录中，只支持authorization_code这一种。
//                .authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
//                // 跳转到授权页面
//                .autoApprove(false)
//                //   用来限制客户端的访问范围，如果是空(默认)的话，那么客户端拥有全部的访问范围。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          用来限制客户端的访问范围，如果是空(默认)的话，那么客户端拥有全部的访问范围。
//                .scopes("all");
//    }
//
//
//    /**
//     * 2.配置端点(令牌管理)
//     */
//
//
//    /*
//     * 密码模式下配置认证管理器AuthenticationManager,并且设置AccessToken的存储介质tokenStore,如果不设置,则会默认使用内存当做存储介质
//     * 而该AuthenticationManager将会注入2个Bean对象用以检查(认证)
//     * 1.ClientDetailsService的实现类JdbcClientDetailsService(检查ClientDetails对象)
//     * 2.UserDetailsService的实现类CustomUserDetailsService(检查UserDetails对象)
//     */
//    // mcp的
//    /*2.1 基于授权模式的端点配置（可自定义多种授权模式）*/
////    @Override
////    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
////        endpoints
////                .authenticationManager(authenticationManager) // 认证管理器
////                .tokenGranter(tokenGranter); // 授权模式
////
////    }
//
//    /*2.2 基于内存的端点配置*/
//        /*
//        authenticationManager：认证管理器。当你选择了password(资源所有者密码)
//    这个授权类型时，就需要指定authenticationManager对象来进行鉴权。
//
//    userDetailsService：用户主体管理服务。如果设置了这个属性，那说明有一个
//    自己的UserDetailsService接口的实现，或者你可以把这个东东设置到全局域上去，当你设置了这个之后，那
//    么refresh_token刷新令牌方式的授权类型流程中就会多包含一个检查步骤，来确保这个账号是否仍然有效。
//
//    authorizationCodeServices：这个属性是用来设置授权服务器的，主要用于
//
//    authorization_code 授权码类型模式。
//
//    implicitGrantService：这个属性用于设置隐式授权模式的状态。
//
//    tokenGranter：如果设置了这个东东(即TokenGranter接口的实现类)，那么授
//    权将会全部交由你来自己掌控，并且会忽略掉以上几个属性。这个属性一般是用
//    作深度拓展用途的，即标准的四种授权模式已经满足不了你的需求时，才会考虑
//    使用这个*/
//    @Override
//    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//        endpoints
//                .authenticationManager(authenticationManager)//认证管理器,用于认证用户名密码是否正确
//                // 定义了授权模式则以下内容全部不需要
////                .pathMapping("/oauth/confirm_access", "/customer/confirm_access")//定制授权同意页面
//                .userDetailsService(passwordUserDetailsService)//密码模式的用户信息管理
//                .authorizationCodeServices(authorizationCodeServices)//授权码服务
//                .tokenServices(tokenService())//令牌管理服务
//                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
//    }
//
//    //
//    //设置授权码模式的授权码如何存取，暂时用内存方式。
//    @Bean
//    public AuthorizationCodeServices authorizationCodeServices() {
//        return new InMemoryAuthorizationCodeServices();
//         }
//// 从tokenCOnfig里复制来的
//    public AuthorizationServerTokenServices tokenService() {
//        DefaultTokenServices service = new DefaultTokenServices();
//        service.setClientDetailsService(clientDetailsService); //客户端详情服务
//        service.setSupportRefreshToken(true); //允许令牌自动刷新
//        service.setTokenStore(tokenStore); //令牌存储策略-内存
//        service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
//        service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3
//        return service;
//    }
//
//        /**
//         * 3.配置令牌安全约束
//         */
//        @Override
//        public void configure (AuthorizationServerSecurityConfigurer security) throws Exception {
//            security.tokenKeyAccess("permitAll()") // oauth/token_key公开
//             .checkTokenAccess("permitAll()") // oauth/check_token公开
//           .allowFormAuthenticationForClients(); // 表单认证，申请令牌
//        }
//    }
//
